﻿/*
 * Copyright 2012 Rene Prost, Registrite ja Infosüsteemide Keskus 
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 */
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq; 
using System.Text;
using NUnit.Framework;
using Spring.Context.Support;
using Xtee.Core.Envelope;
using Xtee.Core.Envelope.Header;
using Xtee.Core.Exceptions;

namespace Xtee.Core.Test
{
    [TestFixture]
    public class FaultSerializerTests
    {
        private string _validSoapFaultFile = @"..\..\ResourceData\SoapFaultExamples\SoapShemaValidSoapFault.xml";
        [Test]
        public void ShouldGenerateValidToSchemaXml()
        { 
            var serializer = new XteeSerializer().WithIndending();
            var fault = new Envelope.Fault();
            fault.Faultcode = "SomeCode23";
            fault.Faultstring = "Some error occured.";
            fault.Faultactor = "http://locahost";
            fault.Detail = "Some';'Exception detail";
            var envelope = new SoapEnvelope() {Body = fault};

            using (var stream = new MemoryStream())
            {
                serializer.Serialize(stream, envelope);
                stream.Position = 0;
                var xml = new StreamReader(stream).ReadToEnd();
                Console.Write(xml);
                Assert.That(xml, Is.EqualTo(File.ReadAllText(_validSoapFaultFile)));
            }
        }
        
        [Test]
        public void ShouldBeAbleToReadValidSoapFault()
         {
            var serializer = new XteeSerializer();

            using (var stream = new MemoryStream(File.ReadAllBytes(_validSoapFaultFile)))
            {
                try
                {
                    serializer.Deserialize<SoapEnvelope>(stream);
                }
                catch (XteeSoapTechnicalFault ex)
                {
                    var fault = ex.Fault;
                    Assert.That(fault.Faultcode, Is.EqualTo("SomeCode23"));
                    Assert.That(fault.Faultstring, Is.EqualTo("Some error occured."));
                    Assert.That(fault.Faultactor, Is.EqualTo("http://locahost"));
                    Assert.That(fault.Detail, Is.EqualTo("Some';'Exception detail"));

                }

            }
        }

        [Test]
        public void ShouldBeAbleToReadFaultGeneratedBySecurityServer()
        {
            var serializer = new XteeSerializer();
            using (var stream = new MemoryStream(File.ReadAllBytes(@"..\..\ResourceData\SoapFaultExamples\fault_variation_2.xml")))
            {
                
                try
                {
                    serializer.Deserialize<SoapEnvelope>(stream);
                }
                catch (XteeSoapTechnicalFault ex)
                {
                    Assert.That(ex.Fault.Faultcode, Is.EqualTo("Client.MissingBody"));
                    Assert.That(ex.Fault.Faultstring, Is.EqualTo("Malformed SOAP message: body missing"));
                    Assert.That(ex.Fault.Faultactor, Is.EqualTo(""));
                    Assert.That(ex.Fault.Detail, Is.EqualTo("81b5060f-2956-4617-8140-93a8e2a339b5"));
                    
                }
                
            }
        }


        [Test]
        public void ShouldBeAbleToReadFaultGeneratedByEtomik()
        {
            var serializer = new XteeSerializer();
            using (var stream = new MemoryStream(File.ReadAllBytes(@"..\..\ResourceData\SoapFaultExamples\fault_variation_3.xml")))
            {
                try
                {
                    serializer.Deserialize<SoapEnvelope>(stream);
                }
                catch (XteeSoapTechnicalFault ex)
                {
                    var fault = ex.Fault as Envelope.Fault;
                    Assert.That(fault.Faultcode, Is.EqualTo("Server.InternalError"));
                    Assert.That(fault.Faultstring, Is.EqualTo("The string '2015-0-17T00:00:00.0000000' is not a valid AllXsd value.----- LOGI ID: 88826510"));
                    Assert.That(fault.Faultactor, Is.EqualTo("Adapter.Etoimik"));
                    Assert.That(fault.Detail, Is.Null);
                }
                
            }
        }

        [Test]
        public void ShouldBeAbleToReadInCaseSomeUnknownDetailContent()
        {
            var expectedDetail = @"Some';'Exception detail
Was unable fully process Fault detail - following is entire raw content:
<detail>
  <faultDetail><![CDATA[Some';'Exception detail]]></faultDetail>
  <somesomeotherdetail>
    <somerandomelement>56</somerandomelement>
    <someotherrandomelement></someotherrandomelement>
  </somesomeotherdetail>
</detail>
";

            var serializer = new XteeSerializer();
            using (var stream = new MemoryStream(File.ReadAllBytes(@"..\..\ResourceData\SoapFaultExamples\fault_variation_5.xml")))
            {
                try
                {
                    serializer.Deserialize<SoapEnvelope>(stream);
                }
                catch (XteeSoapTechnicalFault ex)
                {

                    var fault = ex.Fault;
                    Assert.That(fault.Faultcode, Is.EqualTo("SomeCode23"));
                    Assert.That(fault.Faultstring, Is.EqualTo("Some error occured."));
                    Assert.That(fault.Faultactor, Is.EqualTo("http://locahost"));
                    Assert.That(fault.Detail, Is.InstanceOf<UnprocessedFaultDetail>());
                    var unproccessed = fault.Detail as UnprocessedFaultDetail;
                    Assert.That(unproccessed.ToString(), Is.EqualTo(expectedDetail));
                    Assert.That(unproccessed.Text, Is.EqualTo("Some';'Exception detail"));
                }
                
            }
        }

        [Test]
        public void InCaseCannotResolveSingleTextContentItReturnsEntireRawXmlContent()
        {
            var expectedDetail = @"Was unable to process Fault detail - following is entire raw content:
<detail>
  <somedetail>
    <xsd:string xmlns:xsd=""http://www.w3.org/2001/XMLSchema""><![CDATA[Some';'Exception detail]]></xsd:string>
    <moredetail>
      <somerandomelement>56</somerandomelement>
      <someotherrandomelement></someotherrandomelement>
    </moredetail>
  </somedetail>
  <somesomeotherdetail>
    <somerandomelement>56</somerandomelement>
    <someotherrandomelement></someotherrandomelement>
  </somesomeotherdetail>
</detail>
";
            var serializer = new XteeSerializer();
            using (var stream = new MemoryStream(File.ReadAllBytes(@"..\..\ResourceData\SoapFaultExamples\fault_variation_6.xml")))
            {
                try
                {
                    serializer.Deserialize<SoapEnvelope>(stream);
                }
                catch (XteeSoapTechnicalFault ex)
                {
                    var fault = ex.Fault;
                    Console.Write(fault.ToString());
                    Assert.That(fault.Faultcode, Is.EqualTo("SomeCode23"));
                    Assert.That(fault.Faultstring, Is.EqualTo("Some error occured."));
                    Assert.That(fault.Faultactor, Is.EqualTo("http://locahost"));
                    Assert.That(fault.Detail, Is.InstanceOf<UnprocessedFaultDetail>());
                    Assert.That(fault.Detail.ToString(), Is.EqualTo(expectedDetail));
                }
                
            }
        }
    }
}
